(function (angular) {
    'use strict';

    angular.module('ytong.services').factory('proxyService',proxyService);

    function proxyService($http, $q,$log, Constants, $rootScope, $timeout){

        var promisesCount = 0;

        var TYPE_ADD = "add";
        var TYPE_UPDATE = "update";
        var TYPE_DELETE = "delete";

        function get(URL, object){
            var defer = $q.defer();

            if(object === undefined){
                object = {};
            }
            promisesCount++;

            $http.get(URL, object)
                .then(function(response){

                    if(response.data.success){
                        $log.info("http get request successful. (" + URL + ")");
                        decreasePromise();
                        defer.resolve(response.data);
                    }else{
                        if(response.data.query_result === Constants.QUERY_RESULTS.ERROR){
                            $log.error("http get request failure. (" + URL + ") - " + response.data.log_error);
                            decreasePromise();
                            defer.reject(response.data);
                        }else if(response.data.query_result === Constants.QUERY_RESULTS.NO_RESULTS){
                            $log.info("No entities found. (" + URL + ")");
                            decreasePromise();
                            defer.reject(response.data);
                        }else{
                            $log.info("Query error. (" + URL + ")");
                            defer.reject(response.data);

                        }
                    }

                }, function(response){
                    $log.error("http get request failure. (" + URL + ")");
                    if(response !== undefined){
                        $log.error("http response: " + response);
                    }
                    decreasePromise();
                    defer.reject(response.data);
                });

            return defer.promise;
        };

        function post(URL, object){
            var defer = $q.defer();
            promisesCount++;

            $http.post(URL, object)
                .then(function(response){

                    if(response.data.success){
                        $log.info("http post request successful. (" + URL + ")");
                        decreasePromise();
                        defer.resolve(response.data);
                    }else{
                        $log.error("http post request failure. (" + URL + ") - " + response.data.log_error);
                        decreasePromise();
                        defer.reject();
                    }

                }, function(response){
                    $log.error("http post request failure. (" + URL + ") - " + response.data.log_error);
                    decreasePromise();
                    defer.reject();
                });

            return defer.promise;
        }

        function addEntity(url, entityData) {
            var defer = $q.defer();
            promisesCount++;

            if (entityData !== undefined) {
                entityData.request_type = TYPE_ADD;

                post(url, entityData)
                    .then(function () {
                        $log.info("Entity added successfully.");
                        decreasePromise();
                        defer.resolve();
                    }, function (responseData) {
                        $log.info("Unable to add entity: " + responseData.log_error);
                        decreasePromise();
                        defer.reject();
                    });
            }else{
                $log.info("entityData is undefined (probably bug)");
                decreasePromise();
                defer.reject();
            }

            return defer.promise;
        };

        function updateEntity(url, entityData) {
            var defer = $q.defer();
            promisesCount++;

            if (entityData !== undefined) {
                entityData.request_type = TYPE_UPDATE;

                post(url, entityData)
                    .then(function () {
                        $log.info("Entity updated successfully.");
                        decreasePromise();
                        defer.resolve();
                    }, function (responseData) {
                        $log.info("Unable to update entity: " + responseData.log_error);
                        decreasePromise();
                        defer.reject();
                    });
            }else{
                $log.info("entityData is undefined (probably bug)");
                decreasePromise();
                defer.reject();
            }

            return defer.promise;
        };

        function deleteEntity(url, entityData){
            var defer = $q.defer();
            promisesCount++;

            if (entityData !== undefined) {
                entityData.request_type = TYPE_DELETE;

                post(url, entityData)
                    .then(function () {
                        $log.info("Entity deleted successfully.");
                        decreasePromise();
                        defer.resolve();
                    }, function (responseData) {
                        $log.info("Unable to delete entity: " + responseData.log_error);
                        decreasePromise();
                        defer.reject();
                    });
            }else{
                $log.info("entityData is undefined (probably bug)");
                decreasePromise();
                defer.reject();
            }

            return defer.promise;
        };

        function decreasePromise(){
            promisesCount--;

            if(promisesCount === 0){
                $rootScope.$broadcast('promisesChangedEvent', {
                    isLoading: false
                });
            }
        };

        //interface
        return{
            get: get,
            post: post,
            addEntity: addEntity,
            updateEntity: updateEntity,
            deleteEntity: deleteEntity,
        }
    };

}(angular));